#include "Convert.h"
#include <algorithm> // 用于std::reverse

using namespace yzrilyzr_lang;

namespace yzrilyzr_util{

	String toString(int32_t v, int32_t radix){
		// 处理特殊情况：0
		if(v == 0){
			return String("0");
		}

		// 检查基数有效性
		if(radix < 2 || radix > 36){
			radix=10; // 默认十进制
		}

		String result="";
		bool negative=false;

		// 处理负数
		if(v < 0 && radix == 10){
			negative=true;
			v=-v;
		}

		// 转换数字
		while(v > 0){
			int remainder=v % radix;
			v/=radix;

			// 将数字转换为字符
			char digit[2];
			digit[1]='\0';
			if(remainder < 10){
				digit[0]='0' + remainder;
			} else{
				digit[0]='a' + (remainder - 10);
			}

			result=String(digit) + result;
		}

		// 添加负号（仅十进制）
		if(negative){
			result=String("-") + result;
		}

		return result;
	}

	String toUnsignedString(int32_t v, int32_t radix){
		// 将int32_t转换为uint32_t来处理无符号数
		uint32_t unsignedValue=static_cast<uint32_t>(v);

		// 处理特殊情况：0
		if(unsignedValue == 0){
			return String("0");
		}

		// 检查基数有效性
		if(radix < 2 || radix > 36){
			radix=10; // 默认十进制
		}

		String result="";

		// 转换数字
		while(unsignedValue > 0){
			uint32_t remainder=unsignedValue % radix;
			unsignedValue/=radix;

			// 将数字转换为字符
			char digit[2];
			digit[1]='\0';
			if(remainder < 10){
				digit[0]='0' + remainder;
			} else{
				digit[0]='a' + (remainder - 10);
			}

			result=String(digit) + result;
		}

		return result;
	}

	String toHexString(int32_t v){
		return toUnsignedString(v, 16);
	}
	int32_t parseInt(const yzrilyzr_lang::String & s, int32_t radix){
		bool negative=false;
		int32_t i=0, len=s.length();
		int32_t limit=-Integer_MAX_VALUE;

		if(len > 0){
			char firstChar=s.charAt(0);
			if(firstChar < '0'){ // Possible leading "+" or "-"
				if(firstChar == '-'){
					negative=true;
					limit=Integer_MIN_VALUE;
				} else if(firstChar != '+'){
					throw NumberFormatException::forInputString(s, radix);
				}

				if(len == 1){ // Cannot have lone "+" or "-"
					throw NumberFormatException::forInputString(s, radix);
				}
				i++;
			}
			int32_t multmin=limit / radix;
			int32_t result=0;
			while(i < len){
				// Accumulating negatively avoids surprises near MAX_VALUE
				int32_t digit=codePointToDigit(s.codePointAt(i++), radix);
				if(digit < 0 || result < multmin){
					throw NumberFormatException::forInputString(s, radix);
				}
				result*=radix;
				if(result < limit + digit){
					throw NumberFormatException::forInputString(s, radix);
				}
				result-=digit;
			}
			return negative?result:-result;
		} else{
			throw NumberFormatException::forInputString(s, radix);
		}
	}
	int64_t parseLong(const yzrilyzr_lang::String & s, int32_t radix){
		bool negative=false;
		int64_t i=0, len=s.length();
		int64_t limit=-Long_MAX_VALUE;

		if(len > 0){
			char firstChar=s.charAt(0);
			if(firstChar < '0'){ // Possible leading "+" or "-"
				if(firstChar == '-'){
					negative=true;
					limit=Long_MAX_VALUE;
				} else if(firstChar != '+'){
					throw NumberFormatException::forInputString(s, radix);
				}

				if(len == 1){ // Cannot have lone "+" or "-"
					throw NumberFormatException::forInputString(s, radix);
				}
				i++;
			}
			int64_t multmin=limit / radix;
			int64_t result=0;
			while(i < len){
				// Accumulating negatively avoids surprises near MAX_VALUE
				int64_t digit=codePointToDigit(s.codePointAt(i++), radix);
				if(digit < 0 || result < multmin){
					throw NumberFormatException::forInputString(s, radix);
				}
				result*=radix;
				if(result < limit + digit){
					throw NumberFormatException::forInputString(s, radix);
				}
				result-=digit;
			}
			return negative?result:-result;
		} else{
			throw NumberFormatException::forInputString(s, radix);
		}
	}
	int32_t codePointToDigit(uint32_t cp, int32_t radix){
	// 检查进制范围是否有效
		if(radix < 2 || radix > 36){
			return -1;
		}

		int32_t digit;

		// 处理数字 0-9
		if(cp >= '0' && cp <= '9'){
			digit=cp - '0';
		}
		// 处理大写字母 A-Z
		else if(cp >= 'A' && cp <= 'Z'){
			digit=cp - 'A' + 10;
		}
		// 处理小写字母 a-z
		else if(cp >= 'a' && cp <= 'z'){
			digit=cp - 'a' + 10;
		}
		// 无效字符
		else{
			return -1;
		}

		// 检查数字是否在给定进制范围内
		if(digit >= radix){
			return -1;
		}

		return digit;
	}
}